<?php

class DbItem {

    public /* DbItemMapping */ $mapping = null;
    private $data;
    protected $key_historic;
    public $dirtyflags = Array();
    public /* Boolean */ $new_flag = true;
    public /* Boolean */ $dirty_flag = false;

    public static function create() {
        return new DbItem();
    }

    public function cloneMapping($prototype) {
        $this->mapping = $prototype->mapping;
    }
    public function createMapping() {
        // OVERRIDE
    }
    public function getData() {
        return $this->data;
    }

    public static function instance($content) {
        return new DbItem($content);
    }

    public function __construct($content=null, $mapping=null) {
        if ($mapping != null) {
            $this->mapping = $mapping;
        } else {
            $this->createMapping();
        }
        if ($content != null) {
            $this->new_flag = false;
            $this->data = $content;
        }
        $this->updateKey();
    }

    public function getKey() {
        return $this->key_historic;
    }

    public function updateKey() {
        $this->key_historic = $this->data[$this->mapping->getPrimaryKeyRule()->attributeName];
    }

    public function refresh() {
        $self = DbItemQuery::create(get_class($this))->findId($this->key_historic);
        $this->data = $self->getData();
        $this->dirty_flag = false;
        $this->dirtyflags = Array();
    }

    public function __get($name) {
        if (isset($this->data[$name])) {
            return $this->data[$name];
        } else {
            throw new Exception("Attribute not found");
        }
    }

    public function __set($name, $value) {
        $rules = $this->mapping->getRules();
        if ($rules[$name]->is_writable == true) {
            $this->data[$name] = $value;
            $this->dirty_flag = true;
            $this->dirtyflags[$name] = true;
        } else {
            throw new Exception("ReadOnly Attribute");
        }
    }

    public function store() {
        if ($this->dirty_flag == true) {
            DBLink::getInstance()->store($this);
            $this->dirty_flag = false;
            $this->dirtyflags = Array();
        }
    }

    public function delete() {
        DBLink::getInstance()->delete($this);
    }

}

?>
